import uuid
import hashlib
import hmac
from django.views.decorators.csrf import csrf_exempt
from django.utils import timezone
from django.conf import settings
from rest_framework import status, mixins
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
from .services import PaymentService
from orders.models import Order
from .models import Payment
from .utils import get_wechat_pay_client, generate_nonce_str
from wechatpy.pay import WeChatPayException


class PaymentViewSet(mixins.CreateModelMixin, GenericViewSet):
    """支付视图集"""
    permission_classes = [IsAuthenticated]
    
    def create(self, request, *args, **kwargs):
        """创建支付"""
        order_id = kwargs.get('order_id')
        payment_method = request.data.get('payment_method')
        
        try:
            if payment_method == 'wechat':
                payment, prepay_data = PaymentService.process_wechat_payment(order_id, request.user)
                return Response({
                    'payment_id': payment.id,
                    'prepay_data': prepay_data
                })
            elif payment_method == 'balance':
                payment = PaymentService.process_balance_payment(order_id, request.user)
                return Response({
                    'payment_id': payment.id,
                    'message': '支付成功'
                })
            else:
                return Response({'error': '不支持的支付方式'}, status=status.HTTP_400_BAD_REQUEST)
        except ValueError as e:
            return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({'error': '支付处理失败'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @action(detail=True, methods=['post'], permission_classes=[IsAuthenticated])
    def refund(self, request, pk=None):
        """退款"""
        try:
            payment = Payment.objects.get(id=pk, order__customer=request.user)
        except Payment.DoesNotExist:
            return Response({'error': '支付记录不存在'}, status=status.HTTP_404_NOT_FOUND)
        
        # 检查支付状态
        if payment.status != 'completed':
            return Response({'error': '支付状态不允许退款'}, status=status.HTTP_400_BAD_REQUEST)
        
        try:
            # 调用微信退款API
            wechat_pay = get_wechat_pay_client()
            refund_result = wechat_pay.refund(
                out_trade_no=payment.transaction_id,
                out_refund_no=str(uuid.uuid4()).replace('-', '')[:32],
                total_fee=int(payment.amount * 100),  # 转换为分
                refund_fee=int(payment.amount * 100),
                refund_desc='用户申请退款'
            )
            
            if refund_result['result_code'] == 'SUCCESS':
                # 更新支付和订单状态
                payment.status = 'refunded'
                payment.save()
                
                order = payment.order
                order.status = 'refunded'
                order.save()
                
                return Response({'message': '退款成功'})
            else:
                return Response({'error': '退款失败'}, status=status.HTTP_400_BAD_REQUEST)
        except WeChatPayException as e:
            return Response({'error': f'微信支付错误: {e.return_msg}'}, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({'error': f'退款处理失败: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class WeChatPaymentNotifyViewSet(GenericViewSet):
    """微信支付异步通知视图集"""
    
    @csrf_exempt
    def create(self, request):
        """处理微信支付异步通知"""
        try:
            # 验证通知签名
            wechat_pay = get_wechat_pay_client()
            
            # 处理支付结果通知
            result_data = wechat_pay.parse_payment_result(request.body)
            
            # 更新支付状态
            transaction_id = result_data.get('transaction_id')
            if result_data.get('return_code') == 'SUCCESS' and result_data.get('result_code') == 'SUCCESS':
                payment = PaymentService.handle_payment_notification(
                    transaction_id=transaction_id,
                    payment_status='completed'
                )
                
                return Response({
                    'return_code': 'SUCCESS',
                    'return_msg': 'OK'
                })
            else:
                return Response({
                    'return_code': 'FAIL',
                    'return_msg': '支付失败'
                })
        except Exception as e:
            return Response({
                'return_code': 'FAIL',
                'return_msg': str(e)
            })